﻿#include<stdio.h>
#include<string>
#include<stdlib.h>
#include<windows.h>//系统工具库
#include<iostream>
#include<iomanip>
#include<fstream>

using namespace std;

//预处理
#define OK 1//宏定义OK为1
#define ERROR 0//宏定义ERROR为0
#define OVERFLOW -1//宏定义OVERFLOW为-1
#define MAXSIZE 100//宏定义MAXSIZE为100

typedef char ET;//数据类型char重定义为ET

typedef struct  sq//重定义结构体名为sq
{
	ET* data;//数据的基地址
	int front;//头指针
	int rear;//尾指针
};


void menu()
{
	cout << "****************************\n" ;
	cout << "****循环队列的表示和实现****\n" ;
	cout << "****************************\n" ;
	cout << "*1.元素入队      2.元素出队*\n" ;
	cout << "*3.显示队头      4.显示队尾*\n" ;
	cout << "*5.显示队长      6.全部出队*\n" ;
	cout << "*****0.退出循环队列程序*****\n" ;
	cout << "****************************\n" ;
}

//void menu()//备用简易菜单
//{
//
//	cout << "1.元素入队\n" << "2.元素出队*\n" << "3.显示队头\n" << "4.显示队尾*\n" << "5.显示队长\n" << "6.全部出队*\n" << "0.退出程序" << endl;;
//
//}

int InitSq(sq* Q)//初始化
{
	Q->data = NULL;//初始化为空
	Q->data = (ET*)realloc(Q->data, MAXSIZE * sizeof(ET));//realloc开辟100个ET类型的空间
	Q->front = Q->rear = 0;//头尾指针置空
	if (Q->data == NULL)//如果申请失败则退出
	{
		cout<<"内存申请失败！"<<endl;
		exit(OVERFLOW);
	}
	return OK;
}


int SqDestroy(sq* Q)//销毁队列
{
	if (Q->data == NULL)//若data地址已经为空则直接退出
	{
		return OVERFLOW;
	}

	free(Q->data);//释放data
	Q->data = NULL;
	Q->front = Q->rear = 0;
	return OK;
}

int SqLength(sq* Q)//输出队列长度
{
	return (((Q->rear) - (Q->front)  + MAXSIZE) % MAXSIZE);//计算
}


int SqPush(sq* Q, ET x)//入队
{
	if (((Q->rear)+1) % MAXSIZE == Q->front)
	{
		return OVERFLOW;
	}
	
	Q->data[Q->rear] = x;//x入队尾
	Q->rear = ((Q->rear)+1) % MAXSIZE;//队尾指向队尾的下一个
	return OK;
}

ET SqPop(sq* Q)//出队
{
	if ((Q->front) == (Q->rear) )
	{
		return ERROR;
	}
	
	ET e = 0;
	e = Q->data[Q->front];
	Q->data[Q->front] = 0;
	Q->front = ((Q->front)+1) % MAXSIZE;
	return e;
}

ET SqHead(sq* Q)//显示队头
{
	if (Q->front != Q->rear)
	{
		return (Q->data[Q->front]);
	}
	else
	{
		return ERROR;
	}
}

ET SqEnd(sq* Q)//显示队尾
{
	if (Q->front != Q->rear)
	{
		return (Q->data[(Q->rear) - 1]);
	}
	else
	{
		return ERROR;
	}
}

int SqAll(sq* Q)//全部出队
{
	if ((Q->front) == (Q->rear))
	{
		return ERROR;
	}

	while (!((Q->front) == (Q->rear)))
	{
		cout<< SqPop(Q)<<"出队"<<endl;
	}
	return OK;
}

int main()
{
	sq Q;
	int order = 0;
	InitSq(&Q);//初始化
	do
	{
		system("cls");//清理屏幕
		menu();
		cout << "请选择功能>";
		cin >> order;
		switch (order)
		{
			case 0://退出
				{
					cout << "退出成功！" << endl;
					SqDestroy(&Q);
					break;
				}

			case 1://入队
			{
				ET x=1;
		sqpush:
				cout << "请输入单字符元素(输入#结束入队)>" ;
				cin >> x;
				if (x != '#')
				{
					int y = SqPush(&Q, x);
					if (y == OK)
					{
						goto sqpush;//跳转继续录入
					}
					else if (y == OVERFLOW)
					{
						cout<<"队满！"<<endl;
						break;
					}
				}
				else
				{
					break;
				}
			}

			case 2://出队
			{
				ET e= SqPop(&Q);
				if ( !(e==ERROR) )
				{
					cout << e<<"出队" << endl;
				}
				else
				{
					cout << "队空" << endl;
				}
				system("pause");
				break;
			}

			case 3://显示队头
			{
				ET e = SqHead(&Q);
				if (e == ERROR)
				{
					cout << "队空" << endl;
				}
				else
				{
					cout << "队头为" << e << endl;
				}
				system("pause");
				break;
			}

			case 4://显示队尾
			{
				ET e = SqEnd(&Q);
				if (e == ERROR)
				{
					cout << "队空" << endl;
				}
				else
				{
					cout << "队尾为" << e << endl;
				}
				system("pause");
				break;
			}

			case 5://显示队长度
			{
				cout <<"队长度为" << SqLength(&Q) << endl;
				system("pause");
				break;
			}

			case 6://全部出队
			{
				ET e= SqAll(&Q);
				if (e == ERROR)
				{
					cout << "队空" << endl;
					system("pause");
					break;
				}
				system("pause");
				break;
			}

			default: 
			{
				cout << "选择错误！" << endl; 
				break; 
			}

		}
	} while (order);

	return OK;
}



